package org.hs.phd.odi.tracking.tracker.trackwindow;

import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.Point2D;

import org.hs.phd.common.improc.traversal.PixelTraversalKit;
import org.hs.phd.common.improc.traversal.RGBImagePixelProcessor;
import org.hs.phd.common.improc.traversal.RGBImagePixelTraverser;
import org.hs.phd.odi.tracking.tracker.Histogram;
import org.hs.phd.odi.tracking.tracker.TrackWindow;

import com.googlecode.javacv.cpp.opencv_core.IplImage;

public class RegularGridTrackWindow implements TrackWindow {
	
	private float centerX;
	private float centerY;
	private float width;
	private float height;

	public RegularGridTrackWindow(float centerX, float centerY, float width, float height) {
		this.centerX = centerX;
		this.centerY = centerY;
		this.width = width;
		this.height = height;
	}

	public RegularGridTrackWindow() {
		this(0,0,0,0);
	}

	@Override
	public void calculateHistogram(IplImage frame, Histogram histogram) {
		histogram.calculateFrom(frame, getAsRectangle() );
	}

	private Rectangle getAsRectangle() {
		return new Rectangle((int)Math.round(centerX - width/2.0F), (int)Math.round(centerY - height/2.0F), (int)Math.round(width), (int)Math.round(height));
	}

	@Override
	public Polygon getAsPolygon() {
		Polygon result = new Polygon();
        result.addPoint((int)Math.round( centerX - width/2.0F), (int)Math.round( centerY - height/2.0F));
        result.addPoint((int)Math.round( centerX + width/2.0F), (int)Math.round( centerY - height/2.0F));
        result.addPoint((int)Math.round( centerX + width/2.0F), (int)Math.round( centerY + height/2.0F));
        result.addPoint((int)Math.round( centerX - width/2.0F), (int)Math.round( centerY + height/2.0F));
        return result;	
	}

	@Override
	public void moveToBestMatchingLocationFor(Polygon initialTrackShape) {
		Rectangle box = initialTrackShape.getBounds();
		centerX = box.x + box.width/2.0F;
		centerY = box.y + box.height/2.0F;
		width = box.width;
		height = box.height;
	}

	@Override
	public TrackWindow getCopy() {
		return new RegularGridTrackWindow(centerX, centerY, width, height);
	}

	@Override
	public void moveCenterToPosition(Point2D.Float newPosition) {
		centerX = newPosition.x;
		centerY = newPosition.y;
	}

	@Override
	public Point2D.Float getCenter() {
		return new Point2D.Float(centerX, centerY);
	}

	@Override
	public void traversePixels(IplImage frame, RGBImagePixelProcessor processor) {
		RGBImagePixelTraverser traverser = PixelTraversalKit.createRGBRectangularTraverser(getAsRectangle());
		traverser.traversePixels(frame, processor);
		
	}
	
	@Override
	public double distanceTo(TrackWindow other) {
		java.awt.geom.Point2D.Float center = getCenter();
		java.awt.geom.Point2D.Float center2 = other.getCenter();
		double distance = center.distance(center2);
		return distance;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + java.lang.Float.floatToIntBits(centerX);
		result = prime * result + java.lang.Float.floatToIntBits(centerY);
		result = prime * result + java.lang.Float.floatToIntBits(height);
		result = prime * result + java.lang.Float.floatToIntBits(width);
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		RegularGridTrackWindow other = (RegularGridTrackWindow) obj;
		if (java.lang.Float.floatToIntBits(centerX) != java.lang.Float.floatToIntBits(other.centerX))
			return false;
		if (java.lang.Float.floatToIntBits(centerY) != java.lang.Float.floatToIntBits(other.centerY))
			return false;
		if (java.lang.Float.floatToIntBits(height) != java.lang.Float.floatToIntBits(other.height))
			return false;
		if (java.lang.Float.floatToIntBits(width) != java.lang.Float.floatToIntBits(other.width))
			return false;
		return true;
	}

}
